#include <gtest/gtest.h>
#include "viml/ast.h"
#include <memory>

using namespace viml;

// 测试叶子节点克隆
TEST(ASTCloneTest, NumberLiteralClone) {
    auto original = std::make_unique<NumberLiteral>(42.0, 10, 5);
    auto cloned = original->clone();
    
    ASSERT_NE(cloned, nullptr);
    auto cloned_num = dynamic_cast<NumberLiteral*>(cloned.get());
    ASSERT_NE(cloned_num, nullptr);
    
    EXPECT_EQ(cloned_num->value, 42.0);
    EXPECT_EQ(cloned_num->line, 10);
    EXPECT_EQ(cloned_num->column, 5);
    
    // 修改克隆不应影响原节点
    cloned_num->value = 100.0;
    EXPECT_EQ(original->value, 42.0);
}

TEST(ASTCloneTest, StringLiteralClone) {
    auto original = std::make_unique<StringLiteral>("hello", 20, 10);
    auto cloned = original->clone();
    
    ASSERT_NE(cloned, nullptr);
    auto cloned_str = dynamic_cast<StringLiteral*>(cloned.get());
    ASSERT_NE(cloned_str, nullptr);
    
    EXPECT_EQ(cloned_str->value, "hello");
    EXPECT_EQ(cloned_str->line, 20);
    EXPECT_EQ(cloned_str->column, 10);
    
    // 修改克隆不应影响原节点
    cloned_str->value = "world";
    EXPECT_EQ(original->value, "hello");
}

TEST(ASTCloneTest, IdentifierClone) {
    auto original = std::make_unique<Identifier>("myvar", 15, 3);
    auto cloned = original->clone();
    
    ASSERT_NE(cloned, nullptr);
    auto cloned_id = dynamic_cast<Identifier*>(cloned.get());
    ASSERT_NE(cloned_id, nullptr);
    
    EXPECT_EQ(cloned_id->name, "myvar");
    EXPECT_EQ(cloned_id->line, 15);
}

// 测试表达式节点克隆
TEST(ASTCloneTest, BinaryExpressionClone) {
    auto left = std::make_unique<NumberLiteral>(10.0);
    auto right = std::make_unique<NumberLiteral>(20.0);
    auto original = std::make_unique<BinaryExpression>(
        std::move(left),
        BinaryExpression::Operator::ADD,
        std::move(right),
        5, 0
    );
    
    auto cloned = original->clone();
    ASSERT_NE(cloned, nullptr);
    
    auto cloned_bin = dynamic_cast<BinaryExpression*>(cloned.get());
    ASSERT_NE(cloned_bin, nullptr);
    ASSERT_NE(cloned_bin->left, nullptr);
    ASSERT_NE(cloned_bin->right, nullptr);
    
    auto left_num = dynamic_cast<NumberLiteral*>(cloned_bin->left.get());
    auto right_num = dynamic_cast<NumberLiteral*>(cloned_bin->right.get());
    
    ASSERT_NE(left_num, nullptr);
    ASSERT_NE(right_num, nullptr);
    EXPECT_EQ(left_num->value, 10.0);
    EXPECT_EQ(right_num->value, 20.0);
    EXPECT_EQ(cloned_bin->op, BinaryExpression::Operator::ADD);
}

TEST(ASTCloneTest, UnaryExpressionClone) {
    auto operand = std::make_unique<NumberLiteral>(5.0);
    auto original = std::make_unique<UnaryExpression>(
        UnaryExpression::Operator::MINUS,
        std::move(operand)
    );
    
    auto cloned = original->clone();
    ASSERT_NE(cloned, nullptr);
    
    auto cloned_unary = dynamic_cast<UnaryExpression*>(cloned.get());
    ASSERT_NE(cloned_unary, nullptr);
    ASSERT_NE(cloned_unary->operand, nullptr);
    
    auto operand_num = dynamic_cast<NumberLiteral*>(cloned_unary->operand.get());
    ASSERT_NE(operand_num, nullptr);
    EXPECT_EQ(operand_num->value, 5.0);
    EXPECT_EQ(cloned_unary->op, UnaryExpression::Operator::MINUS);
}

TEST(ASTCloneTest, ListLiteralClone) {
    std::vector<std::unique_ptr<Expression>> elements;
    elements.push_back(std::make_unique<NumberLiteral>(1.0));
    elements.push_back(std::make_unique<NumberLiteral>(2.0));
    elements.push_back(std::make_unique<NumberLiteral>(3.0));
    
    auto original = std::make_unique<ListLiteral>(std::move(elements));
    auto cloned = original->clone();
    
    ASSERT_NE(cloned, nullptr);
    auto cloned_list = dynamic_cast<ListLiteral*>(cloned.get());
    ASSERT_NE(cloned_list, nullptr);
    EXPECT_EQ(cloned_list->elements.size(), 3);
    
    for (size_t i = 0; i < 3; ++i) {
        auto elem = dynamic_cast<NumberLiteral*>(cloned_list->elements[i].get());
        ASSERT_NE(elem, nullptr);
        EXPECT_EQ(elem->value, static_cast<double>(i + 1));
    }
}

// 测试语句节点克隆
TEST(ASTCloneTest, LetStatementClone) {
    auto value = std::make_unique<NumberLiteral>(42.0);
    auto original = std::make_unique<LetStatement>("x", std::move(value));
    
    auto cloned = original->clone();
    ASSERT_NE(cloned, nullptr);
    
    auto cloned_let = dynamic_cast<LetStatement*>(cloned.get());
    ASSERT_NE(cloned_let, nullptr);
    EXPECT_EQ(cloned_let->name, "x");
    ASSERT_NE(cloned_let->value, nullptr);
    
    auto value_num = dynamic_cast<NumberLiteral*>(cloned_let->value.get());
    ASSERT_NE(value_num, nullptr);
    EXPECT_EQ(value_num->value, 42.0);
}

TEST(ASTCloneTest, IfStatementClone) {
    auto condition = std::make_unique<NumberLiteral>(1.0);
    
    std::vector<std::unique_ptr<Statement>> then_body;
    then_body.push_back(std::make_unique<LetStatement>("a", std::make_unique<NumberLiteral>(1.0)));
    
    std::vector<std::unique_ptr<Statement>> else_body;
    else_body.push_back(std::make_unique<LetStatement>("b", std::make_unique<NumberLiteral>(2.0)));
    
    auto original = std::make_unique<IfStatement>(
        std::move(condition),
        std::move(then_body),
        std::move(else_body)
    );
    
    auto cloned = original->clone();
    ASSERT_NE(cloned, nullptr);
    
    auto cloned_if = dynamic_cast<IfStatement*>(cloned.get());
    ASSERT_NE(cloned_if, nullptr);
    ASSERT_NE(cloned_if->condition, nullptr);
    EXPECT_EQ(cloned_if->then_body.size(), 1);
    EXPECT_EQ(cloned_if->else_body.size(), 1);
}

TEST(ASTCloneTest, ProgramClone) {
    std::vector<std::unique_ptr<Statement>> statements;
    statements.push_back(std::make_unique<LetStatement>("x", std::make_unique<NumberLiteral>(1.0)));
    statements.push_back(std::make_unique<LetStatement>("y", std::make_unique<NumberLiteral>(2.0)));
    
    auto original = std::make_unique<Program>(std::move(statements));
    auto cloned = original->clone();
    
    ASSERT_NE(cloned, nullptr);
    auto cloned_prog = dynamic_cast<Program*>(cloned.get());
    ASSERT_NE(cloned_prog, nullptr);
    EXPECT_EQ(cloned_prog->statements.size(), 2);
    
    // 验证第一条语句
    auto stmt1 = dynamic_cast<LetStatement*>(cloned_prog->statements[0].get());
    ASSERT_NE(stmt1, nullptr);
    EXPECT_EQ(stmt1->name, "x");
}

// 测试深度克隆
TEST(ASTCloneTest, DeepCloneIndependence) {
    // 创建一个复杂的表达式树
    auto inner_left = std::make_unique<NumberLiteral>(5.0);
    auto inner_right = std::make_unique<NumberLiteral>(3.0);
    auto inner_expr = std::make_unique<BinaryExpression>(
        std::move(inner_left),
        BinaryExpression::Operator::ADD,
        std::move(inner_right)
    );
    
    auto outer_right = std::make_unique<NumberLiteral>(2.0);
    auto original = std::make_unique<BinaryExpression>(
        std::move(inner_expr),
        BinaryExpression::Operator::MUL,
        std::move(outer_right)
    );
    
    auto cloned = original->clone();
    ASSERT_NE(cloned, nullptr);
    
    // 修改克隆的深层节点
    auto cloned_bin = dynamic_cast<BinaryExpression*>(cloned.get());
    ASSERT_NE(cloned_bin, nullptr);
    auto inner = dynamic_cast<BinaryExpression*>(cloned_bin->left.get());
    ASSERT_NE(inner, nullptr);
    auto inner_left_num = dynamic_cast<NumberLiteral*>(inner->left.get());
    ASSERT_NE(inner_left_num, nullptr);
    
    inner_left_num->value = 999.0;
    
    // 验证原节点未受影响
    auto orig_inner = dynamic_cast<BinaryExpression*>(original->left.get());
    ASSERT_NE(orig_inner, nullptr);
    auto orig_inner_left = dynamic_cast<NumberLiteral*>(orig_inner->left.get());
    ASSERT_NE(orig_inner_left, nullptr);
    EXPECT_EQ(orig_inner_left->value, 5.0);
}
